package com.ruoyi.mp.service.impl;

import com.ruoyi.mp.api.domain.MpAccount;
import com.ruoyi.mp.mapper.MpAccountMapper;
import com.ruoyi.mp.service.IMpAccountService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 公众号账号Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-18
 */
@Service
public class MpAccountServiceImpl implements IMpAccountService
{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MpAccountMapper mpAccountMapper;
    @Autowired
    WxMpService wxMpService;
    @Override
    public void loadWxMpConfigStorages(){
        MpAccount mpAccount = new MpAccount();
        logger.info("加载公众号配置...");
        List<MpAccount> accountList = this.mpAccountMapper.selectMpAccountList(mpAccount);
        if (accountList == null || accountList.isEmpty()) {
            logger.info("未读取到公众号配置，请在管理后台添加");
            return;
        }
        logger.info("加载到{}条公众号配置",accountList.size());
        accountList.forEach(this::addAccountToRuntime);
        logger.info("公众号配置加载完成");
    }
    /**
     * 查询公众号账号
     *
     * @param id 公众号账号主键
     * @return 公众号账号
     */
    @Override
    public MpAccount selectMpAccountById(Long id)
    {
        return mpAccountMapper.selectMpAccountById(id);
    }

    /**
     * 查询公众号账号列表
     *
     * @param mpAccount 公众号账号
     * @return 公众号账号
     */
    @Override
    public List<MpAccount> selectMpAccountList(MpAccount mpAccount)
    {
        return mpAccountMapper.selectMpAccountList(mpAccount);
    }

    /**
     * 新增公众号账号
     *
     * @param mpAccount 公众号账号
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMpAccount(MpAccount mpAccount)
    {
        this.addAccountToRuntime(mpAccount);
        return mpAccountMapper.insertMpAccount(mpAccount);
    }

    /**
     * 修改公众号账号
     *
     * @param mpAccount 公众号账号
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMpAccount(MpAccount mpAccount)
    {
        this.removeAccountToRuntime(mpAccount);
        this.addAccountToRuntime(mpAccount);
        return mpAccountMapper.updateMpAccount(mpAccount);
    }

    /**
     * 批量删除公众号账号
     *
     * @param ids 需要删除的公众号账号主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteMpAccountByIds(Long[] ids)
    {
        MpAccount mpAccount = this.mpAccountMapper.selectMpAccountById(ids[0]);
        this.removeAccountToRuntime(mpAccount);
        return mpAccountMapper.deleteMpAccountByIds(ids);
    }

    /**
     * 添加账号到当前程序，如首次添加需初始化configStorageMap
     * @param entity
     */
    private synchronized void addAccountToRuntime(MpAccount entity){
        String appid = entity.getAppId();
        WxMpDefaultConfigImpl config = entity.toWxMpConfigStorage();
        try {
            wxMpService.addConfigStorage(appid,config);
        }catch (NullPointerException e){
            logger.info("需初始化configStorageMap...");
            Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4);
            configStorages.put(appid,config);
            wxMpService.setMultiConfigStorages(configStorages,appid);
        }
    }

    /**
     * 删除账号到当前程序，如首次添加需初始化configStorageMap
     * @param entity
     */
    private synchronized void removeAccountToRuntime(MpAccount entity){
        String appid = entity.getAppId();
        WxMpDefaultConfigImpl config = entity.toWxMpConfigStorage();
        try {
            wxMpService.removeConfigStorage(appid);
        }catch (NullPointerException e){
            logger.info("需初始化configStorageMap...");
            Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4);
            configStorages.put(appid,config);
            wxMpService.setMultiConfigStorages(configStorages,appid);
        }
    }
}
